import React, { useState, useEffect, useRef } from 'react';
import { Input, InputRef, Tag } from 'antd';
import { TweenOneGroup } from 'rc-tween-one';
import { PlusOutlined } from '@ant-design/icons';

// 给Form.Item添加value和onChange接口
export default function Keywords<ValueType extends string | {value: string;key:string}>(props: {
  value?: ValueType[];
  onChange?: (value: ValueType[])=>void;
  beforeAdd?: (value: string)=>boolean;
  beforeDelete?: (value: ValueType)=>boolean;
  disableAdd?: boolean;
  disableDelete?: boolean;
  min?: number;
}){
  const [inputVisible, setVisible] = useState<boolean>(false);
  const [inputValue, setInputValue] = useState<string>('');

  const tagArr = props.value || [];
  const setTagArr = props.onChange || function() {};

  const inputRef = useRef<InputRef>(null);

  const getValue = (val: ValueType)=>{
    return typeof val === 'string' ? val : val.value;
  }

  const getKey = (val: ValueType)=>{
    return typeof val === 'string' ? val : val.key;
  }

  const handleClose = (removedTag: ValueType) => {
    let flag = true;
    if(props.beforeDelete){
      flag = props.beforeDelete(removedTag);
    }
    if(flag){
      const tags = tagArr.filter(tag => getKey(tag) !== getKey(removedTag));
      setTagArr(tags);
    }
  };

  const showInput = () => {
    setVisible(true);
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(e.target.value);
  };

  const handleInputConfirm = () => {
    if(!inputValue || tagArr.map(getValue).includes(inputValue)){
      return;
    }
    let flag = true;
    if(props.beforeAdd){
      flag = props.beforeAdd(inputValue);
    }
    if (flag) {
      if(!tagArr.length){
        setTagArr([inputValue]);
      }else{
        const newArr = [...tagArr, typeof tagArr[0] === 'string' ? inputValue : {value: inputValue,key: inputValue}];
        setTagArr(newArr);
      }

    }
    setVisible(false);
    setInputValue('');
  };

  return (
    <div>
      <TweenOneGroup
        enter={{
          scale: 0.8,
          opacity: 0,
          type: 'from',
          duration: 100,
          onComplete: e => {},
        }}
        leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
        appear={false}
      >
        {tagArr.map((tag) => {
          const tagElem = (
            <Tag
              closable={props.disableDelete ? false : (props.min !== undefined ? tagArr.length > props.min : true)}
              onClose={(e: React.MouseEvent) => {
                e.preventDefault();
                handleClose(tag);
              }}
            >
              {getValue(tag)}
            </Tag>
          );

          return (
            <span key={getKey(tag)} style={{ display: 'inline-block', margin: '5px 0' }}>
        {tagElem}
      </span>
          );
        })}
        {inputVisible && (
          <Input
            ref={inputRef}
            type="text"
            size="small"
            style={{ width: 78 }}
            value={inputValue}
            onChange={handleInputChange}
            onBlur={handleInputConfirm}
            onPressEnter={handleInputConfirm}
            autoFocus
          />
        )}
        {!props.disableAdd && !inputVisible && (
          <Tag onClick={showInput}>
            <PlusOutlined /> 添加
          </Tag>
        )}
      </TweenOneGroup>
    </div>
  );
};
